package org.mobai.flow.strategy.impl;

import lombok.AllArgsConstructor;
import org.camunda.bpm.model.bpmn.builder.AbstractFlowNodeBuilder;
import org.camunda.bpm.model.bpmn.builder.StartEventBuilder;
import org.camunda.bpm.model.bpmn.instance.camunda.CamundaFormField;
import org.mobai.flow.pojo.bpmn.FormProperty;
import org.mobai.flow.pojo.bpmn.Node;
import org.mobai.flow.pojo.bpmn.node.StartEvent;
import org.mobai.flow.strategy.BpmnStrategy;
import org.mobai.flow.strategy.context.BpmnBuildContext;
import org.mobai.flow.utils.FlowUtil;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @author hyk
 */
@AllArgsConstructor
@Service
public class StartEventBpmnImpl implements BpmnStrategy<StartEvent> {
    private BpmnBuildContext bpmnBuildContext;

    /**
     * 构建开始事件节点
     *
     * @param flowNodeBuilder 流程节点构建器
     * @param node 开始事件节点
     * @return 返回构建后的流程节点构建器
     */
    @Override
    public AbstractFlowNodeBuilder build(AbstractFlowNodeBuilder flowNodeBuilder, StartEvent node, Map<String, String> nodeMap) {
        // 设置节点ID
        flowNodeBuilder.id(node.getId());
        // 设置节点名称
        flowNodeBuilder.name(node.getName());
        // 设置表单属性
        setCamundaFormFieldAndProperty(node.getFormProperties(), (StartEventBuilder) flowNodeBuilder);
        // 设置执行监听器
        setCamundaExecutionListener(flowNodeBuilder, node.getExecutionListeners());
        // 获取子节点
        Node child = node.getChild();
        // 如果子节点非空
        if (Objects.nonNull(child)) {
            // 递归构建子节点
            return bpmnBuildContext.buildBpmn(flowNodeBuilder, child,nodeMap);
        }
        // 返回流程节点构建器
        return flowNodeBuilder;
    }

    /**
     * 将表单属性列表中的表单属性设置为Camunda表单字段和属性
     *
     * @param formPropertiesList 表单属性列表，包含需要设置的表单属性
     * @param startEventBuilder StartEvent的构建器，用于创建Camunda流程的开始事件
     */
    private void setCamundaFormFieldAndProperty(List<FormProperty> formPropertiesList, StartEventBuilder startEventBuilder) {
        // 遍历表单属性列表，对每个表单属性执行以下操作
        Optional.ofNullable(formPropertiesList).ifPresent(formProperties -> formProperties.forEach(formProperty -> {
            // 创建Camunda表单字段并设置其ID、标签和类型
            CamundaFormField camundaFormField = startEventBuilder.camundaFormField()
                    .camundaId(formProperty.getId())
                    .camundaLabel(formProperty.getName())
                    .camundaType("string")
                    .getElement();
            // 使用FlowUtil工具类将表单属性设置到Camunda表单字段上
            FlowUtil.setCamundaProperties(formProperty, camundaFormField);
        }));
    }
}
